﻿

using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using JumbotPay.Utils;
using JumbotPay.DBUtility;
using JumbotPay.Common;
using System.Data.SqlClient;
using System.Threading;
using JumbotPay.API.WxPayAPI;
namespace JumbotPay.DAL
{
    /// <summary>
    /// 自动任务
    /// </summary>
    public class AutoTaskDAL
    {
        public static string SiteUrl = System.Configuration.ConfigurationManager.AppSettings["JumbotPay:SiteUrl"];
        public static string WebRoot = System.Configuration.ConfigurationManager.AppSettings["JumbotPay:WebRoot"];
        public static Hashtable HT_CheckPayState = new Hashtable();

        public static Thread Thread_CheckPayState = null;

        public static Thread Thread_SendPayNotice = null;


        public static void SaveLogs(string _file, string _output)
        {
            System.IO.StreamWriter sw = new System.IO.StreamWriter(WebRoot + "\\Logs\\" + _file + ".log", true, System.Text.Encoding.UTF8);
            sw.WriteLine(System.DateTime.Now.ToString() + "\t" + _output);
            sw.Close();
            sw.Dispose();
        }
        /// <summary>
        /// 读取Config参数
        /// </summary>
        public static string ReadConfig(string name, string key)
        {
            System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
            string _file = (WebRoot + name + ".config").Replace("\\\\", "\\");
            XmlDoc.Load(_file);
            System.Xml.XmlNodeList xnl = XmlDoc.GetElementsByTagName(key);
            if (xnl.Count == 0)
                return "";
            else
            {
                System.Xml.XmlNode mNode = xnl[0];
                return mNode.InnerText;
            }
        }
        /// <summary>
        /// 保存Config参数
        /// </summary>
        public static void UpdateConfig(string name, string key, string nValue)
        {
            if (ReadConfig(name, key) != "")
            {
                string _file = (WebRoot + name + ".config").Replace("\\\\", "\\");
                try
                {
                    System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
                    XmlDoc.Load(_file);
                    System.Xml.XmlNodeList elemList = XmlDoc.GetElementsByTagName(key);
                    System.Xml.XmlNode mNode = elemList[0];
                    mNode.InnerText = nValue;
                    System.Xml.XmlTextWriter xw = new System.Xml.XmlTextWriter(new System.IO.StreamWriter(_file));
                    xw.Formatting = System.Xml.Formatting.Indented;
                    XmlDoc.WriteTo(xw);
                    xw.Close();
                }
                catch { }
            }
        }
        public static SqlConnection _conn
        {
            get
            {
                string dbServerIP = ReadConfig("\\_data\\config\\conn", "dbServerIP");
                string dbLoginName = ReadConfig("\\_data\\config\\conn", "dbLoginName");
                string dbLoginPass = ReadConfig("\\_data\\config\\conn", "dbLoginPass");
                string dbName = ReadConfig("\\_data\\config\\conn", "dbName");
                string ConnectionString = "Data Source=" + dbServerIP + ";Initial Catalog=" + dbName + ";User ID=" + dbLoginName + ";Password=" + dbLoginPass + ";Pooling=true;max pool size=1024;";
                return new SqlConnection(ConnectionString);
            }
        }
        /// <summary>
        /// 在线支付成功，通知app的notify地址
        /// </summary>
        /// <param name="_appid"></param>
        /// <param name="_out_trade_no"></param>
        /// <returns></returns>
        private static bool UpdateOrder(string _appid, string _out_trade_no, string _pay_order_id)
        {
            try
            {
                if (_pay_order_id == "")
                    _pay_order_id = _out_trade_no;
                using (DbOperHandler _doh = new SqlDbOperHandler(_conn))
                {
                    _doh.Reset();
                    _doh.ConditionExpress = "appid=@appid";
                    _doh.AddConditionParameter("@appid", _appid);
                    object[] value = _doh.GetFields("jpay_app", "notify_url,appkey");
                    if (value != null)
                    {
                        string _notify_url = value[0].ToString();
                        string key = value[1].ToString();
                        _doh.Reset();
                        _doh.ConditionExpress = "out_trade_no=@out_trade_no and pay_status=0";
                        _doh.AddConditionParameter("@out_trade_no", _out_trade_no);
                        string _order_id = _doh.GetField("jpay_order", "order_id").ToString();//根据流水号反推业务订单号
                        if (_order_id != "")
                        {
                            string[] array1 = { "order_id=" + _order_id, "pay_status=0", "pay_order_id=" + _pay_order_id };
                            string sign1 = JumbotPay.Utils.Strings.GetSign(array1, key);
                            string _posturl = _notify_url;
                            string _postData = JumbotPay.Utils.Strings.GetParaStr(array1, sign1);
                            string _html = JumbotPay.Utils.HttpHelper.Post_Http(_posturl, _postData, System.Text.Encoding.GetEncoding("utf-8"));
                            try
                            {
                                if (_html == "success")
                                {
                                    _doh.Reset();
                                    _doh.ConditionExpress = "appid=@appid and out_trade_no=@out_trade_no and pay_status=0";
                                    _doh.AddConditionParameter("@appid", _appid);
                                    _doh.AddConditionParameter("@out_trade_no", _out_trade_no);
                                    _doh.AddFieldItem("pay_status", 1);
                                    _doh.AddFieldItem("pay_time", System.DateTime.Now.ToString());
                                    _doh.AddFieldItem("notified", 1);
                                    _doh.AddFieldItem("NoticeTimes", 1);
                                    _doh.AddFieldItem("pay_order_id", _pay_order_id);

                                    _doh.Update("jpay_order");
                                    return true;
                                }
                                else
                                {
                                    _doh.Reset();
                                    _doh.ConditionExpress = "appid=@appid and out_trade_no=@out_trade_no and pay_status=0";
                                    _doh.AddConditionParameter("@appid", _appid);
                                    _doh.AddConditionParameter("@out_trade_no", _out_trade_no);
                                    _doh.AddFieldItem("pay_status", 1);
                                    _doh.AddFieldItem("pay_time", System.DateTime.Now.ToString());
                                    _doh.AddFieldItem("notified", 0);
                                    _doh.AddFieldItem("pay_order_id", _pay_order_id);
                                    _doh.Update("jpay_order");
                                    CYQ.Data.Log.WriteLogToTxt(_posturl + "\r\n" + _postData + "\r\n" + _html);
                                    return false;
                                }
                            }
                            catch (Exception ex)
                            {
                                CYQ.Data.Log.WriteLogToTxt(_posturl + "\r\n" + _postData + "\r\n" + ex.Message);
                                return false;
                            }
                        }
                        else
                            return false;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            catch (Exception ex)
            {
                CYQ.Data.Log.WriteLogToTxt(ex.Message);
                return false;
            }
        }
        #region 检测支付状态
        public static void CheckPayState()
        {
            while (true)
            {
                Thread.Sleep(1 * 1000);//做1秒钟的准备工作
                string _time2 = System.DateTime.Now.ToString("HH:mm:ss");
                System.Diagnostics.Stopwatch oTime = new System.Diagnostics.Stopwatch();
                oTime.Start(); //记录起始时间
                using (DbOperHandler _doh = new SqlDbOperHandler(_conn))
                {

                    _doh.Reset();
                    _doh.SqlCmd = "SELECT TOP 10 appid,out_trade_no,account_wxpay" +
                        " FROM [View_Order]" +
                        " WHERE pay_status=0 and pay_method='wxpay' AND ((MustCheckPayState=1) OR (datediff(minute,order_time,getdate())>5 and datediff(minute,order_time,getdate())<2880))" +
                        " ORDER BY newid()";
                    DataTable dt = _doh.GetDataTable();
                    int _tasknum = dt.Rows.Count;
                    if (_tasknum > 0)
                    {
                        for (int i = 0; i < _tasknum; i++)
                        {
                            #region 循环操作
                            string appid = dt.Rows[i][0].ToString();
                            string _out_trade_no = dt.Rows[i][1].ToString();
                            string _account_wxpay = dt.Rows[i][2].ToString();
                            try
                            {
                                string result = new OrderQuery().Run("", _out_trade_no, _account_wxpay);//不要暴露流水号
                                if (result.Contains("trade_state=SUCCESS"))
                                {
                                    if (UpdateOrder(appid, _out_trade_no, ""))
                                    {
                                        SaveLogs("CatchWxOrder", "补漏处理了订单：" + _out_trade_no);
                                    }
                                }
                            }
                            catch (WxPayException ex)
                            {
                                CYQ.Data.Log.WriteLogToTxt("CheckPayState" + "\r\n" + ex.Source + "\r\n" + ex.Message);
                            }
                            catch (Exception ex)
                            {
                                CYQ.Data.Log.WriteLogToTxt("CheckPayState" + "\r\n" + ex.Source + "\r\n" + ex.Message);
                            }
                            #endregion
                        }
                        dt.Clear();
                        dt.Dispose();
                        Thread.Sleep(300);
                        oTime.Stop();   //记录结束时间
                    }
                    else
                    {
                        dt.Clear();
                        dt.Dispose();
                        Thread.Sleep(20 * 1000);
                    }
                }
            }
        }
        #endregion
        #region 发送通知消息
        public static void SendPayNotice()
        {
            while (true)
            {
                Thread.Sleep(1 * 1000);//做1秒钟的准备工作
                string _time2 = System.DateTime.Now.ToString("HH:mm:ss");
                System.Diagnostics.Stopwatch oTime = new System.Diagnostics.Stopwatch();
                oTime.Start(); //记录起始时间
                using (DbOperHandler _doh = new SqlDbOperHandler(_conn))
                {

                    _doh.Reset();
                    _doh.SqlCmd = "SELECT TOP 1 appid,out_trade_no,order_id,pay_order_id" +
                        " FROM [jpay_order]" +
                        " WHERE pay_status=1 and NoticeTimes<20 and notified=0" +
                        " ORDER BY newid()";
                    DataTable dt = _doh.GetDataTable();
                    int _tasknum = dt.Rows.Count;
                    if (_tasknum > 0)
                    {
                        for (int i = 0; i < _tasknum; i++)
                        {
                            #region 循环操作
                            string _appid = dt.Rows[i][0].ToString();
                            string _out_trade_no = dt.Rows[i][1].ToString();
                            string _order_id = dt.Rows[i][2].ToString();
                            string _pay_order_id = dt.Rows[i][3].ToString();
                            try
                            {

                                _doh.Reset();
                                _doh.ConditionExpress = "appid=@appid";
                                _doh.AddConditionParameter("@appid", _appid);
                                object[] value = _doh.GetFields("jpay_app", "notify_url,appkey");
                                if (value != null)
                                {
                                    string _notify_url = value[0].ToString();
                                    string key = value[1].ToString();
                                    if (_order_id != "")
                                    {
                                        string[] array1 = { "order_id=" + _order_id, "pay_status=0", "pay_order_id=" + _pay_order_id };
                                        string sign1 = JumbotPay.Utils.Strings.GetSign(array1, key);
                                        string _posturl = _notify_url;
                                        string _postData = JumbotPay.Utils.Strings.GetParaStr(array1, sign1);
                                        string _html = JumbotPay.Utils.HttpHelper.Post_Http(_posturl, _postData, System.Text.Encoding.GetEncoding("utf-8"));

                                        if (_html == "success")
                                        {
                                            _doh.Reset();
                                            _doh.SqlCmd = "update jpay_order set notified=1,NoticeTimes=NoticeTimes+1 where out_trade_no='" + _out_trade_no + "'";
                                            _doh.ExecuteSqlNonQuery();
                                            SaveLogs("CatchNotice", "补漏通知了订单：" + _out_trade_no);
                                        }
                                        else
                                        {
                                            _doh.Reset();
                                            _doh.SqlCmd = "update jpay_order set NoticeTimes=NoticeTimes+1 where out_trade_no='" + _out_trade_no + "'";
                                            _doh.ExecuteSqlNonQuery();
                                            CYQ.Data.Log.WriteLogToTxt(_posturl+"\n"+_html);
                                        }
                                    }
                                }
                                else
                                {
                                }
                            }
                            catch (Exception ex)
                            {
                                _doh.Reset();
                                _doh.SqlCmd = "update jpay_order set NoticeTimes=NoticeTimes+1 where out_trade_no='" + _out_trade_no + "'";
                                _doh.ExecuteSqlNonQuery();
                                CYQ.Data.Log.WriteLogToTxt("SendPayNotice" + "\r\n" + ex.Source + "\r\n" + ex.Message);
                            }
                            #endregion
                        }
                        dt.Clear();
                        dt.Dispose();
                        Thread.Sleep(300);
                        oTime.Stop();   //记录结束时间
                    }
                    else
                    {
                        dt.Clear();
                        dt.Dispose();
                        Thread.Sleep(20 * 1000);
                    }
                }
            }
        }
        #endregion
    }
}
